#include "Cliente.h"

Cliente::Cliente(string archivo,char letra ) {
	this->colaMensajeSalas = new Cola<MensajeSalas>(archivo.c_str(), letra);
	this->colaMensajeUsuarios = new Cola<MensajeUsuarios> (archivo.c_str(), letra + 1);
	this->colaMensajeNuevoCliente = new Cola<MensajeNuevoCliente>(archivo.c_str(), letra + 2);
	this->colaMensajeConectarASala = new Cola<MensajeConectarASala>(archivo.c_str(), letra + 3);
	this->colaMensajeNuevoMensaje = new Cola<MensajeNuevoMensaje>(archivo.c_str(), letra + 4);
	this->idCliente = -1;
	this->idSala = -1;
}

Cliente::~Cliente() {
	delete this->colaMensajeSalas;
	delete this->colaMensajeUsuarios;
	delete this->colaMensajeNuevoCliente;
	delete this->colaMensajeConectarASala;
	delete this->colaMensajeNuevoMensaje;
}

vector<string> Cliente::enviarPeticionListaDeSalas() {
	//Peticion
	MensajeSalas peticion;
	peticion.mtype = PETICION;
	peticion.idUsuario = idCliente;
	this->colaMensajeSalas->escribir(peticion);
	//Respuesta
	vector<string> salas;
	MensajeSalas respuesta;
	if (this->colaMensajeSalas->leer(RESPUESTA + idCliente, &respuesta) == sizeof(MensajeSalas) - sizeof(long)) {
		while(respuesta.idUsuario!=-1)
		{
			salas.push_back(respuesta.nombreSala);
			if (this->colaMensajeSalas->leer(RESPUESTA + idCliente, &respuesta) != sizeof(MensajeSalas) - sizeof(long))
				return salas;
		}
	}
	return salas;
}

vector<string> Cliente::enviarPeticionListaDeUsuarios() {
	//Peticion
	MensajeUsuarios peticion;
	peticion.mtype = PETICION;
	peticion.idUsuario = idCliente;
	peticion.idSala = idSala;
	this->colaMensajeUsuarios->escribir(peticion);
	//Respuesta
	vector<string> usuarios;
	MensajeUsuarios respuesta;
	if (this->colaMensajeUsuarios->leer(RESPUESTA + idCliente, &respuesta) == sizeof(MensajeUsuarios) - sizeof(long)) {
		while(respuesta.idUsuario!=-1)
		{
			usuarios.push_back(respuesta.nombreUsuario);
			if (this->colaMensajeUsuarios->leer(RESPUESTA + idCliente, &respuesta) == sizeof(MensajeUsuarios) - sizeof(long))
				return usuarios;
		}
	}
	return usuarios;
}

bool Cliente::enviarPeticionClienteNuevo(string apodo) {
	strcpy(this->apodo, apodo.c_str());
	//1ero Pido que me asignen un id (si todavia no me lo asignaron)
	MensajeNuevoCliente peticion;
	peticion.mtype = PETICION;
	MensajeNuevoCliente respuesta;
	if(this->idCliente == -1) {
		peticion.id = -1;
		strcpy(peticion.apodo, "");
		this->colaMensajeNuevoCliente->escribir(peticion);
		//Respuesta de id asignado
		if(this->colaMensajeNuevoCliente->leer(RESPUESTA, &respuesta) == sizeof(MensajeNuevoCliente) - sizeof(long))
			this->idCliente = respuesta.id;
		else
			return false;
	}
	//Luego envio el apodo con el id asignado
	peticion.id = this->idCliente;
	strcpy(peticion.apodo, apodo.c_str());
	this->colaMensajeNuevoCliente->escribir(peticion);
	//Si el apodo es único recibo la confirmación del server
	if(this->colaMensajeNuevoCliente->leer(RESPUESTA + peticion.id, &respuesta) == sizeof(MensajeNuevoCliente) - sizeof(long))
		if(respuesta.id != -1)
			return true;
	return false;
}

bool Cliente::enviarPeticionConectarASala(int idSala, string nombreSala) {
	MensajeConectarASala peticion;
	peticion.mtype = PETICION;
	peticion.idUsuario = idCliente;
	peticion.idSala = idSala;
	strcpy(peticion.nombreSala, nombreSala.c_str());
	this->colaMensajeConectarASala->escribir(peticion);
	MensajeConectarASala respuesta;
	if (this->colaMensajeConectarASala->leer(RESPUESTA + idCliente, &respuesta) == sizeof(MensajeConectarASala) - sizeof(long)) {
		if (respuesta.idSala != -1) {
			this->idSala = respuesta.idSala;
			return true;
		}
	}
	return false;
}

string Cliente::recibirMensaje() {
	MensajeNuevoMensaje respuesta;
	if(this->colaMensajeNuevoMensaje->leer(RESPUESTA + this->idCliente, &respuesta) == sizeof(MensajeNuevoMensaje) - sizeof(long)) {
		if(respuesta.conectoASala)
			return strcat(strcat(respuesta.apodo, " se conectó a la sala de chat el "), Util::getAsciiTime().c_str());
		else if(strcmp(respuesta.mensaje, "salir") == 0)
			return strcat(strcat(respuesta.apodo, " dejó la sala de chat el "), Util::getAsciiTime().c_str());
		return strcat(strcat(strcat(strcat(respuesta.apodo, " dijo el "), Util::getAsciiTime().c_str()), ": "), respuesta.mensaje);
	}
	return "";
}

void Cliente::enviarMensaje(string mensaje) {
	MensajeNuevoMensaje peticion;
	peticion.mtype = PETICION;
	peticion.conectoASala = false;
	peticion.idUsuario = idCliente;
	strcpy(peticion.apodo, this->apodo);
	strcpy(peticion.mensaje, mensaje.c_str());
	this->colaMensajeNuevoMensaje->escribir(peticion);
}
